@using System.Text.Encodings.Web
@using Microsoft.JSInterop;
@inject IJSRuntime JS
@using BlazorDatasheet.Render;
@implements IDisposable;
@using Microsoft.AspNetCore.Components.Web.Virtualization;
@using System.Collections.Immutable
@using System.Reflection
@using System.Text
@using BlazorDatasheet.DataStructures.Geometry
@using BlazorDatasheet.DataStructures.Util
@using BlazorDatasheet.Util
@using Microsoft.Extensions.Primitives
<div
    style="height:@(_cellLayoutProvider.TotalHeight)px; width: @(_cellLayoutProvider.TotalWidth)px;"
    class="@GetContainerClassString()"
    theme="@Theme"
    @onmouseover="() => IsMouseInsideSheet = true"
    @onmouseout="() => IsMouseInsideSheet = false">

    @if (Sheet != null)
    {
        <div>
            <!-- Column headers -->
            <div style="display: flex; flex-direction: column; justify-content: start;">

                @if (ShowColHeadings)
                {
                    <div style="display: flex; flex-direction: row;" class="sheet-row @(StickyHeadings ? "col-sticky" : "col-nonsticky")">
                        @if (ShowRowHeadings)
                        {
                            <!-- the little bit outside to the left of first col header -->
                            <div class="sheet-cell row-head column-head"
                                 style="@CssUtil.GetCellWidthStyles(-1, 1, _cellLayoutProvider); height: @(_cellLayoutProvider.ColHeadingHeight)px;
                                 display: inline-block;@(StickyHeadings ? "position: sticky; left: 0; z-index:2;" : "")">
                                <div class="cell"></div>
                            </div>
                        }
                        <div id="filler-left-0" style="min-width: @(Viewport.Left)px; display: block; float: left; height: 1px;"></div>

                        <ColumnHeadingsRenderer
                            OnMouseDown="HandleColumnHeaderMouseDown"
                            OnMouseUp="HandleColumnHeaderMouseUp"
                            OnMouseOver="HandleColumnHeaderMouseOver"
                            NVisibleCols="Viewport.VisibleRegion.Width"
                            VisibleColStart="Viewport.VisibleRegion.Left"
                            CellLayoutProvider="_cellLayoutProvider"
                            Sheet="Sheet"/>

                    </div>
                }

                <div id="filler-top" @ref="_fillerTop" style="min-height: @(Viewport?.Top)px; min-width:@(_cellLayoutProvider.TotalWidth)px; display: block;"></div>

                <div id="last-row" style="display: flex; flex-direction: row;">

                    @if (ShowRowHeadings)
                    {
                        <div id="rowHeadings" class="@(StickyHeadings ? "row-sticky" : "")">
                            <RowHeadingsRenderer
                                OnMouseDown="HandleRowHeaderMouseDown"
                                OnMouseUp="HandleRowHeaderMouseUp"
                                OnMouseOver="HandleRowHeaderMouseOver"
                                NVisibleRows="Viewport.VisibleRegion.Height"
                                VisibleRowStart="Viewport.VisibleRegion.Top"
                                Sheet="Sheet"
                                CellLayoutProvider="_cellLayoutProvider"/>
                        </div>
                    }


                    <div id="filler-left-1" @ref="_fillerLeft1" style="float:right; min-width: @(Viewport.Left)px; height: @(RenderedInnerSheetHeight)px;"></div>

                    <div @ref="_innerSheet" style="width:@(RenderedInnerSheetWidth)px;height: @(RenderedInnerSheetHeight)px;display: block;">
                        @for (int rowIndex = Viewport.VisibleRegion.Top; rowIndex <= Viewport.VisibleRegion.Bottom; rowIndex++)
                        {
                            var row = rowIndex;
                            var rowHeight = @_cellLayoutProvider.ComputeHeight(row, 1);
                            <div @key="row" style="height:@(rowHeight)px">
                                @for (int j = Viewport.VisibleRegion.Left; j <= Viewport.VisibleRegion.Right; j++)
                                {
                                    var col = j;
                                    var cell = _visualSheet.GetVisualCell(row, col);
                                    var colWidth = @cell.Width;
                                    <div
                                        @onpointerup="e => HandleCellMouseUp(row, col, e.MetaKey, e.CtrlKey, e.ShiftKey)"
                                        @ondblclick="e => HandleCellDoubleClick(row, col, e.MetaKey, e.CtrlKey, e.ShiftKey)"
                                        @onpointerenter="e => HandleCellMouseOver(row, col)"
                                        @onpointerdown="e => HandleCellMouseDown(row, col, e.MetaKey, e.CtrlKey, e.ShiftKey)"
                                        @key="col"
                                        style="
                                            width:@(colWidth)px;
                                            max-width:@(colWidth)px;
                                            height:@(rowHeight)px;
                                            max-height:@(rowHeight)px;"
                                        class="sheet-cell">
                                        <CascadingValue Value="Sheet" IsFixed="true">
                                            <CellRenderer
                                                IconColor="@cell.Format?.IconColor"
                                                CellFormatStyleString="@cell.FormatStyleString"
                                                Icon="@GetIconRenderFragment(cell.Icon)"
                                                IsDirty="SheetIsDirty || DirtyCells.Contains(new CellPosition(row, col))">
                                                <ItemTemplate>
                                                    <DynamicComponent
                                                        Type="@GetCellRendererType(cell.CellType)"
                                                        Parameters="@getCellRendererParameters(Sheet, cell)">
                                                    </DynamicComponent>
                                                </ItemTemplate>
                                            </CellRenderer>
                                        </CascadingValue>
                                    </div>
                                }
                            </div>
                        }
                    </div>

                    <div id="filler-right" @ref="_fillerRight" style="float:left;min-width: @(Viewport.DistanceRight)px; height:@(RenderedInnerSheetHeight)px;"></div>

                    <!-- Merged cells -->
                    @if (Sheet.Cells.AnyMerges() && this.Viewport is not null)
                    {
                        var mergesInView = Sheet.Cells.GetMerges(this.Viewport.VisibleRegion);
                        @foreach (var merge in mergesInView)
                        {
                            var row = merge.Top;
                            var col = merge.Left;
                            var cell = _visualSheet.GetVisualCell(row, col);

                            <div id="merge"
                                 style="@GetAbsoluteCellPositionStyles(row, col, merge.Height, merge.Width)"
                                 class="sheet-cell"
                                 @onmouseup="e => HandleCellMouseUp(row, col, e.MetaKey, e.CtrlKey, e.ShiftKey)"
                                 @ondblclick="e => HandleCellDoubleClick(row, col, e.MetaKey, e.CtrlKey, e.ShiftKey)"
                                 @onmouseover="e => HandleCellMouseOver(row, col)"
                                 @onmousedown="e => HandleCellMouseDown(row, col, e.MetaKey, e.CtrlKey, e.ShiftKey)">
                                <CascadingValue Value="Sheet" IsFixed="true">
                                    <CellRenderer
                                        IconColor="@cell.Format?.IconColor"
                                        CellFormatStyleString="@cell.FormatStyleString"
                                        IsDirty="SheetIsDirty || DirtyCells.Contains(new CellPosition(row, col))">
                                        <ItemTemplate>
                                            <DynamicComponent
                                                Type="@GetCellRendererType(cell.CellType)"
                                                Parameters="@getCellRendererParameters(Sheet, new VisualCell(row, col, Sheet))">
                                            </DynamicComponent>
                                        </ItemTemplate>
                                    </CellRenderer>
                                </CascadingValue>
                            </div>
                        }
                    }

                    <EditorOverlayRenderer
                        @ref="_editorManager"
                        Sheet="Sheet"
                        DefaultCellTypes="_defaultCellTypeDefinitions"
                        CustomCellTypes="CustomCellTypeDefinitions"
                        CellLayoutProvider="_cellLayoutProvider"/>
                </div>

                <div id="filler-bottom" @ref="_fillerBottom" style="min-height: @(Viewport?.DistanceBottom)px; min-width:@(1)px;"></div>
            </div>
        </div>
    }

    <!-- entire size of sheet to force scrollbars. Includes width of row headers/columns-->
    <div id="sheet_whole"
         @ref="_wholeSheetDiv"
         style="position:absolute; top:0; 
                     left:0;
                     min-height:@(_cellLayoutProvider.TotalHeight))px; 
                     max-height:@(_cellLayoutProvider.TotalHeight))px; 
                     min-width:@(_cellLayoutProvider.TotalWidth))px;
                     max-width:@(_cellLayoutProvider.TotalWidth))px;
                     pointer-events: none;
                     z-index: 0;">

        <SelectionRenderer
            SelectionExpanded="HandleSelectionExpanded"
            Sheet="Sheet"
            CellLayoutProvider="_cellLayoutProvider"/>
    </div>
</div>